package Entity;

import java.util.*;

import Controller.*;

/**
 * This is one of the reports.
 * this report is for periodic time, and it will be produced to the company manager.
 * @author Shahar Shelli
 *
 */
public class PeriodicReport extends Report
{
	private int[] NumOfComplete;
	private int[] NumOfCanceled;
	private int[][] WeeklyDisabledHour;
	private Date start;
	
	/**
	 * is the constructor. it will call the super constructor and also set the number of canceled orders and number of completed orders.
	 * @param s= the start date.
	 * @param e= the end date. e and s will determine the period of time.
	 * @param des= the description for the report.(optional that's why we need this constructor)
	 */
	public PeriodicReport(Date s,Date e,String des)
	{
		super(e,des);
		this.start=new Date(s.getTime());
		this.NumOfCanceled=new int[6];
		this.NumOfComplete=new int[6];
		this.WeeklyDisabledHour=new int [6][4];
		for(int i=0; i<6; i++)
		{
			GregorianCalendar calendar = new GregorianCalendar();
			Date st=new Date(start.getTime());
			for(int j=0; j<4; i++)
			{
				calendar.setTime(start);
				calendar.add(Calendar.DATE, j*7);
				st.setTime(calendar.getTime().getTime());
				Date en=new Date(st.getTime());
				calendar.setTime(st);
				calendar.add(Calendar.DATE, 7);
				st.setTime(calendar.getTime().getTime());
				DisabledPlace[] d=DBcontroller.getNumOfDisabled(st, en,i);
				this.WeeklyDisabledHour[i][j]=d.length;
			}
			this.NumOfComplete[i]=DBcontroller.getCompleteOrder(s,e,i);
			this.NumOfCanceled[i]=DBcontroller.getUnCompleteOrder(s,e,i);
		}
	}
	/**
	 * is the constructor. it will call the super constructor and also set the number of canceled orders and number of completed orders.
	 * @param s= the start date.
	 * @param e= the end date. e and s will determine the period of time.
	 */
	public PeriodicReport(Date s,Date e)
	{
		super(e,"");
		this.start=new Date(s.getTime());
		this.NumOfCanceled=new int[6];
		this.NumOfComplete=new int[6];
		this.WeeklyDisabledHour=new int [6][4];
		for(int i=0; i<6; i++)
		{
			GregorianCalendar calendar = new GregorianCalendar();
			Date st=new Date(start.getTime());
			for(int j=0; j<4; i++)
			{
				calendar.setTime(start);
				calendar.add(Calendar.DATE, j*7);
				st.setTime(calendar.getTime().getTime());
				Date en=new Date(st.getTime());
				calendar.setTime(st);
				calendar.add(Calendar.DATE, 7);
				st.setTime(calendar.getTime().getTime());
				DisabledPlace[] d=DBcontroller.getNumOfDisabled(st, en,i);
				this.WeeklyDisabledHour[i][j]=d.length;
			}
			this.NumOfComplete[i]=DBcontroller.getCompleteOrder(s,e,i);
			this.NumOfCanceled[i]=DBcontroller.getUnCompleteOrder(s,e,i);
		}
	}
	// ***********need to be deleted
	public PeriodicReport(Date s,Date e,int [] comp,int [] canc,int[][]weekly) {
		super(e,"");
		this.start=new Date(s.getTime());
		this.NumOfComplete=comp;
		this.NumOfCanceled=canc;
		this.WeeklyDisabledHour=weekly;
	}
	//*************
	/**
	 * is a function for validate the input. it will only check that the start date is before the end date.
	 * @param s= start date.
	 * @param e= end date.
	 * @param des= the description 
	 * @param p= the parking lot number.
	 * @return true or false if everything is ok.
	 */
	public boolean Validate(Date s,Date e,String des,int p)
	{
		if(s.after(e))
			return false;
		return true;
	}
	
	// the get functions.
	public int getNumOfComplete(int p)
	{
		return this.NumOfComplete[p-1];
	}
	
	public int getNumOfCanceled(int p)
	{
		return this.NumOfCanceled[p-1];
	}
	
	public int[] getWeeklyDisabled(int p)
	{
		return this.WeeklyDisabledHour[p-1];
	}
	
	public Date getStart() {
		return start;
	}
	
	public int getMedianComplete()
	{
		Arrays.sort(this.NumOfComplete);
		return this.NumOfComplete[this.NumOfComplete.length/2];
	}
	
	public int getMedianCancel()
	{
		Arrays.sort(this.NumOfCanceled);
		return this.NumOfCanceled[this.NumOfCanceled.length/2];
	}
	
	public int getDisabledWeeklyMed(int week)
	{
		int []arr=new int[6];
		for(int i=0; i<6; i++)
			arr[i]=this.WeeklyDisabledHour[i][week];
		Arrays.sort(arr);
		return arr[2];
	}
	
	public int[] getCompleteFrequencyDist()
	{
		Arrays.sort(this.NumOfComplete);
		int[]arr=new int[this.NumOfComplete[this.NumOfComplete.length-1]]; for(int k=0; k<arr.length; k++) arr[k]=0;
		for(int i=0; i<this.NumOfComplete.length; i++)
			arr[this.NumOfComplete[i]-1]++;
		return arr;
	}
	
	public int[] getCancelFrequencyDist()
	{
		Arrays.sort(this.NumOfCanceled);
		int[]arr=new int[this.NumOfCanceled[this.NumOfCanceled.length-1]]; for(int k=0; k<arr.length; k++) arr[k]=0;
		for(int i=0; i<this.NumOfCanceled.length; i++)
			arr[this.NumOfCanceled[i]-1]++;
		return arr;
	}
	
	public int[] getWeeklyFrequencyDist(int week)
	{
		int[] temp=new int[this.NumOfCanceled.length]; 
		for(int j=0; j<temp.length; j++)
			temp[j]=this.WeeklyDisabledHour[j][week-1];
		Arrays.sort(temp);
		int[]arr=new int[temp[3]]; for(int k=0; k<arr.length; k++) arr[k]=0;
		for(int i=0; i<temp.length; i++)
			arr[temp[i]-1]++;
		return arr;
	}
	
	// the set functions.
	public void setNumOfComplete(int[] numOfComplete) {
		NumOfComplete = numOfComplete;
	}
	
	public void setNumOfCanceled(int[] numOfCanceled) {
		NumOfCanceled = numOfCanceled;
	}
	
	public void setWeeklyDisabledHour(int[][] weeklyDisabledHour) {
		WeeklyDisabledHour = weeklyDisabledHour;
	}
	
	public void setStart(Date start) {
		this.start = start;
	}
}
